<template>
    <div class="radio-button">
        <button
            v-for="item in options"
            :disabled="item.disabled"
            :key="item.value"
            :class="['radio-item', item.value === active && 'active', item.disabled && 'disabled']"
            @click.stop="handleNavClick(item, $event)"
        >
            <slot
                :name="item.value"
                :option="item"
                :active="item.value === active"
                >{{ item.label }}</slot
            >
        </button>
        <div class="active-bar"></div>
    </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
type Value = number | string | undefined
interface Option {
    label: string
    value: Value
    disabled?: boolean
    [key: string]: unknown
}

const active = defineModel<Value>({ default: '', required: false })
defineProps<{ options: Option[] }>()
const emits = defineEmits<{
    change: [value: Value, data: Option]
}>()

const left = ref('1.5')
const width = ref('0')
const handleNavClick = (item: Option, event: MouseEvent) => {
    const { offsetLeft, offsetWidth } = event.currentTarget as HTMLDivElement
    left.value = `${offsetLeft}px`
    width.value = `${offsetWidth}px`
    active.value = item.value
    emits('change', item.value, item)
}

onMounted(() => {
    const selectedButton = document.querySelector('.active') as HTMLDivElement
    if (selectedButton) {
        const { offsetLeft, offsetWidth } = selectedButton
        left.value = `${offsetLeft}px`
        width.value = `${offsetWidth}px`
    }
})
</script>

<style lang="less" scoped>
.radio-button {
    display: flex;
    display: inline-flex;
    padding: 1.5px;
    line-height: 26px;
    background-color: var(--color-fill-2);
    border-radius: var(--border-radius-small);
    position: relative;
    user-select: none;

    .active-bar {
        height: 30px;
        position: absolute;
        top: 1.5px;
        bottom: 1.5px;
        left: v-bind('left');
        width: v-bind('width');
        color: rgb(var(--primary-6));
        background-color: var(--color-bg-5);
        transition: left 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
    }

    .radio-item {
        z-index: 1;
        position: relative;
        display: inline-block;
        color: var(--color-text-2);
        font-size: 14px;
        line-height: 26px;
        background-color: transparent;
        border-radius: var(--border-radius-small);
        cursor: pointer;
        transition: all 0.1s cubic-bezier(0, 0, 1, 1);
        padding: 2px 12px;
        outline: none;
        border: none;

        &:not(:first-of-type):before {
            position: absolute;
            top: 50%;
            left: -2px;
            display: block;
            width: 1px;
            height: 14px;
            background-color: var(--color-neutral-3);
            transform: translateY(-50%);
            transition: all 0.1s cubic-bezier(0, 0, 1, 1);
            content: '';
        }

        &.active {
            color: rgb(var(--primary-6));
            transition: all 0.1s cubic-bezier(0.645, 0.045, 0.355, 1);

            &:before {
                opacity: 0;
            }

            & + .radio-item {
                &:before {
                    opacity: 0;
                }
            }
        }

        &:hover {
            color: rgb(var(--primary-6));
        }

        &.disabled {
            color: var(--color-text-4);
            cursor: not-allowed;
            background-color: rgb(var(--color-bg-6));
        }
    }
}
</style>
